package com.ug.common.utils;

import cn.hutool.core.util.StrUtil;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.lionsoul.ip2region.xdb.Searcher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.util.FileCopyUtils;

import java.io.InputStream;

/**
 * @Author LY
 * @create 2024/8/2 17:32
 * @Description 计算机IP地址解析为区域地址
 */
public class IpRegionUtil {

    private static final Logger logger = LoggerFactory.getLogger(IpRegionUtil.class);

    private static Searcher searcher;

    private static volatile IpRegionUtil ipRegionUtil = null;

    private IpRegionUtil() {}

    static {
        try {
            // 文件读取
            InputStream inputStream = new ClassPathResource("ip2region.xdb").getInputStream();
            // 输入流转换字节流
            byte[] dbBinStr = FileCopyUtils.copyToByteArray(inputStream);
            // 创建一个完全基于内存的查询对象
            searcher = Searcher.newWithBuffer(dbBinStr);
        } catch (Exception e) {
            logger.error("构建本地Ip缓存失败:{}", e);
        }
    }

    /**
     * 创建实例
     */
    public static IpRegionUtil getInstance() {
        if (ipRegionUtil == null) {
            synchronized (IpRegionUtil.class) {
                if (ipRegionUtil == null) {
                    ipRegionUtil = new IpRegionUtil();
                }
            }
        }
        return ipRegionUtil;
    }

    /**
     * IP地址
     * @param ip ip地址
     * @return 归属地
     */
    public String getRegion(String ip) {
        try {
            // 中国|0|上海|上海市|联通；美国|0|犹他|盐湖城|0
            String regionInfo = searcher.search(ip);
            return getCityInfo(regionInfo, ip);
        } catch (Exception e) {
            logger.error("IP地址异常 {} : {}", ip, e);
        }
        return null;
    }

    /**
     * 解析城市信息，国内显示城市名，国外显示国家名
     */
    private String getCityInfo(String regionInfo, String ip) {
        if (!StrUtil.isEmpty(regionInfo)) {
            //-------------------------------------------------------
            //searchIpInfo 的数据格式： 国家|区域|省份|城市|ISP
            //192.168.31.160 0|0|0|内网IP|内网IP
            //47.52.236.180 中国|0|香港|0|阿里云
            //220.248.12.158 中国|0|上海|上海市|联通
            //164.114.53.60 美国|0|华盛顿|0|0
            String[] splitIpInfo = regionInfo.split("\\|");
            IpRegion region = new IpRegion();
            region.setIp(ip);
            region.setSearchInfo(regionInfo);
            region.setCountry(splitIpInfo[0]);
            region.setRegion(splitIpInfo[1]);
            region.setProvince(splitIpInfo[2]);
            region.setCity(splitIpInfo[3]);
            region.setIsp(splitIpInfo[4]);
            logger.info("详细信息 : {}", region);
            //--------------国内属地返回省份--------------
            if ("中国".equals(region.getCountry())){
                if (!"0".equals(region.getCity())){
                    return region.getCountry() + " " + region.getProvince() + " " + region.getCity() + " " + region.getIsp();
                }
                return region.getProvince();
            }
            //------------------内网 IP----------------
            if ("0".equals(region.getCountry())){
                if ("内网IP".equals(region.getIsp())){
                    return "内网IP";
                }
                else return "";
            }
            //--------------国外属地返回国家--------------
            else {
                return region.getCountry();
            }
        }
        return "未知IP";
    }

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    @ToString
    static class IpRegion{
        /**查询的ip地址*/
        private String ip;
        /**解析的信息*/
        private String searchInfo;
        /**国家*/
        private String country;
        /**区域*/
        private String region;
        /**省份*/
        private String province;
        /**城市*/
        private String city;
        /**运营服务商*/
        private String isp;
    }
}
